package com.hontech.bvapp2.device

import com.hontech.bvapp2.device.cp.Cargo
import com.hontech.bvapp2.device.cp.Door
import com.hontech.bvapp2.device.cp.Drop
import com.hontech.bvapp2.device.cp.Heat
import com.hontech.bvapp2.utils.log
import com.hontech.bvapp2.utils.postEvent
import serial.codec.ByteView
import serial.codec.u16
import serial.codec.u32
import java.security.MessageDigest

class LogEvent(val content: String)

object Back {
    private const val STATUS = 0
    private const val OTA_START = 1
    private const val OTA_TRANSLATE = 2
    private const val OTA_COMPLETE = 3

    suspend fun ota(buf: ByteArray, dst: Int, cb: (Int) -> Unit) {
        val size = buf.size
        DeviceConn.simpleReqOta(dst, OTA_START, size.u32()).parse()
        var id = 0
        var index = 0
        while (index < size) {
            var n = size - index
            if (n > 220) {
                n = 220
            }
            val bw = ByteView(buf, index, n)
            DeviceConn.simpleReqOta(dst, OTA_TRANSLATE, id.u16(), bw).parse()
            id += 1
            index += n
            cb(index * 100 / size)
        }
        val md5 = MessageDigest.getInstance("MD5").digest(buf)
        DeviceConn.simpleReqOta(dst, OTA_COMPLETE, ByteView(md5)).parse()
    }

    fun onLog(frame: Frame) {
        val bw = ByteView()
        frame.parse(bw)
        val msg = bw.toString()
        val cp = Address.getName(frame.src)
        val content = "$cp:$msg"
        log("日志:$content")
        postEvent(LogEvent(content))
    }

    fun onNotify(frame: Frame) {
        val cmd = frame.cmd()
        if (cmd != STATUS) {
            return
        }
        val src = frame.src
        when (src) {
            Address.HEAT -> Heat.onStatus(frame)
            Address.DROP -> Drop.onStatus(frame)
            Address.CARGO2, Address.CARGO1 -> Cargo.onStatus(frame)
            Address.DOOR -> Door.onStatus(frame)
        }
    }
}